home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’92 / HyperInitMaker... / TinyInit < prev   
Encoding:
Text File  |  1992-06-19  |  42.7 KB  |  1,339 lines  |  [TEXT/EDIT]

  1. -- HyperINIT, a hack for MacHack -- Quick Debug version 1992 June 19
  2. -- Copyright 1992 Itty Bitty Computers
  3.  
  4. global UpperStr:R[256], myHandles:P, QuickDraw:R[256], Intl0:P, HCardX:L, 
  5. global myXcmdBlock:R[128], newXcmdBlock:P, toknType:C, doMyCommAd:P
  6. global funMod:L, expnPtr:P, expnValu:R[268], expnType:C, exValPtr:P -- parser stuff
  7. global clicker:L, resType:C, resValue:L, currentX:L -- ClickLoc & the result
  8. global NameList:P, OffList:P, CommNames:L, FuncNames:L, GlobNames:L, ResWords:L
  9. -- each item in OffList: 0=nameoffs,4=linkoffs,8=+resId&recur/-code#/type,10=data
  10. -- first of ResWords is ItemDelimiter, NumberFormat, then chunkies
  11. global ActiveXcmdBlk:P, XgrafPort:P, WinSeqNum:L, tempChar:C, Stripper:L
  12. global myExit:R[64],iRect:R,pRect:R
  13.  
  14. on HyperINIT
  15.   --Debugger
  16.   inline *myExit,$48D0,$FFFF -- also hand-patch param pop in glue exit code
  17.   add 24 to myExit.long[16]
  18.   --debug CodeResource
  19.   InitializeAll true -- as required by Toolbox etc.
  20.   put "StartUp" into WorkingString
  21.   get DoCommand(WorkingStringAdr(),CommNames)
  22.   ShowInit 256
  23.   inline *myExit,$4CD0,$FFFF,$4E75
  24. end HyperINIT
  25.  
  26. on ErrorOffQuick
  27.   --- DebugStr ";g"
  28.   ShowInit 257
  29.   inline *myExit,$4CD0,$FFFF,$4E75
  30.   --- DebugStr ";g"
  31. end ErrorOffQuick
  32.  
  33. on ShowInit theID -- sorry, guys, I ran out of time...
  34.   exit ShowInit
  35.   ---
  36.   put GetResource("ICN#",theID) into hand
  37.   if hand = nil then exit ShowInit
  38.   OpenPort myPort
  39.   setRect iRect,0,0,32,32
  40.   setRect pRect,00,00,32,32 --- ??
  41.   HLock hand
  42.   put hand@.long+128 into myXcmdBlock.baseAddr
  43.   put 4 into myXcmdBlock.rowBytes
  44.   put 0 into myXcmdBlock.bounds.topLeft
  45.   put 32*65536+32 into myXcmdBlock.bounds.botRight
  46.   CopyBits myXcmdBlock,myPort@.portBits,iRect,pRect,3,nil
  47.   put hand@.long into myXcmdBlock.baseAddr
  48.   CopyBits myXcmdBlock,myPort@.portBits,iRect,pRect,1,nil
  49. end ShowInit
  50.  
  51. on TerminateString astr,thestr
  52.   --- DebugStr ";g"
  53.   put thestr@.str into astr@.str
  54.   put astr+1 into expnPtr
  55.   ZapString astr
  56.   Getokenn
  57.   --- DebugStr ";g"
  58. end TerminateString
  59.  
  60. function DoCommand thestr,theList
  61.   --- DebugStr ";g"
  62.   INLINE $9EFC,$0190,+400
  63.   put CPUstackPtr() into fraim
  64.   TerminateString fraim+128,thestr
  65.   put LookupName(theList+0,OffList,NameList) into offs
  66.   if offs is not 0 then
  67.     get HandlePeekWord(OffList,offs+8)
  68.     if it>0 then 
  69.       if CallCode(offs,fraim,16,0) is false then return false
  70.       if expnPtr@.chr>space then 
  71.         return DisposeIfHandle(chartonum(expnType),expnValu.long)
  72.       else if fraim@.passflag then 
  73.         if expnValu.long is not nil then DisposHandle expnValu.long
  74.         return DoCommand(fraim+128,HandlePeekLong(OffList,8))
  75.       else return true
  76.     else return DoMyCommand(-it)
  77.   else return false
  78.   --- DebugStr ";g"
  79. end DoCommand
  80.  
  81. on TextCommand 
  82.   --- DebugStr ";g"
  83.   if ActiveXcmdBlk@.request=1 then get CommNames
  84.     else get HandlePeekLong(OffList,8)
  85.   if DoCommand(ActiveXcmdBlk@.inargs.long,it) then 
  86.     put expnValu.long into ActiveXcmdBlk@.outargs1.long
  87.   else put 1 into ActiveXcmdBlk@.resultx
  88.   --- DebugStr ";g"
  89. end TextCommand
  90.  
  91. on EvalExpn 
  92.   --- DebugStr ";g"
  93.   INLINE $9EFC,$0104,+260
  94.   TerminateString CPUstackPtr(),ActiveXcmdBlk@.inargs.long
  95.   if ParseExpn(chartonum("H"),false) then
  96.     put expnValu.long into ActiveXcmdBlk@.outargs1.long
  97.   else put 1 into ActiveXcmdBlk@.resultx
  98.       put ActiveXcmdBlk@.outargs1.long into aptr
  99.       inline *aptr
  100.       --- DebugStr ";dm @@a0;g"
  101. end EvalExpn
  102.  
  103. on tryForXcmd 
  104.   --- DebugStr ";g"
  105.   put LookupName(CommNames,OffList,NameList) into offs
  106.   if offs is not 0 then
  107.     put ActiveXcmdBlk into expnValu.long
  108.     if HandlePeekByte(OffList,offs+10)<128 then
  109.       put ActiveXcmdBlk into expnValu.str
  110.       put Nextoken into WorkingString
  111.       AppendChar " "
  112.       AppendString expnValu.str
  113.       put DoCommand(WorkingStringAdr(),offs) into didit
  114.     else put DoCommand(WorkingStringAdr()-512,offs) into didit
  115.     if didit then put expnValu.long into ActiveXcmdBlk@.outargs1.long
  116.       else put 1 into ActiveXcmdBlk@.resultx
  117.   else put 2 into ActiveXcmdBlk@.resultx
  118.   --- DebugStr ";g"
  119. end tryForXcmd
  120.  
  121. on notImplemented 
  122.   --- DebugStr ";g"
  123.   put "unimplementedcallback" into Nextoken
  124.   tryForXcmd
  125.   --- DebugStr ";g"
  126. end notImplemented
  127.  
  128. on fieldAccess
  129.   DebugStr "oops"
  130. end fieldAccess
  131.  
  132. on ShellHook
  133.   DebugStr "oops"
  134. end ShellHook
  135.  
  136. on SimpleCallback 
  137.   --- DebugStr ";g"
  138.   get ActiveXcmdBlk@.request
  139.   if it=4 then -- 004,stringmatch
  140.       put ActiveXcmdBlk@.inargs.long into aptr
  141.       inline *aptr
  142.       --- DebugStr ";dm @a0;g"
  143.       put ActiveXcmdBlk@.inargs.off4.long into aptr
  144.       inline *aptr
  145.       --- DebugStr ";dm @a0 20;g"
  146.     get OffsetString(ActiveXcmdBlk@.inargs.long, ¬
  147.       StrLength(ActiveXcmdBlk@.inargs.long@.str),ActiveXcmdBlk@.inargs.off4.long)
  148.     if it>0 then get it+ActiveXcmdBlk@.inargs.off4.long-1
  149.     put it into ActiveXcmdBlk@.outargs1.long
  150.   else if it=6 then -- 006,zerobytes
  151.     put ActiveXcmdBlk@.inargs.long into aptr
  152.     put ActiveXcmdBlk@.inargs.off4.long into nbytes
  153.     if aptr mod 2 + nbytes mod 2 = 0 then repeat nbytes div 2
  154.       put 0 into aptr@.int
  155.       add 2 to aptr
  156.       end repeat
  157.     else repeat nbytes
  158.       put chartonum(0) into aptr@.chr
  159.       add 1 to aptr
  160.       end repeat
  161.   else if it=18 then -- 018,getglobal
  162.     put ActiveXcmdBlk@.inargs.long@.str into Nextoken
  163.     if LeftEx(true,1) then -- -- ** -2C2+858+140
  164.       if expnType is not "H" then ConvertType chartonum("H")
  165.       if expnValu.long=nil then 
  166.         put NewHandleClear(2) into expnValu.long
  167.         put (expnValu.long = nil) into ActiveXcmdBlk@.resultx
  168.       else if HandToHand(expnValu.ptrtype) is not 0 then
  169.         put 1 into ActiveXcmdBlk@.resultx
  170.         put 0 into expnValu.long
  171.         end if
  172.       put expnValu.long into ActiveXcmdBlk@.outargs1.long
  173.     else put 1 into ActiveXcmdBlk@.resultx
  174.       put ActiveXcmdBlk@.outargs1.long into aptr
  175.       inline *aptr
  176.       --- DebugStr ";dm @@a0;g"
  177.   else if it=19 then -- 019,setglobal
  178.     put ActiveXcmdBlk@.inargs.long@.str into Nextoken
  179.     if LeftEx(false,1) then
  180.       put ActiveXcmdBlk@.inargs.off4.long into aptr
  181.       if HandToHand(aptr) is not 0 then
  182.         put 1 into ActiveXcmdBlk@.resultx
  183.       else if PutGlobal(expnValu.off4.long,chartonum("H"),aptr)
  184.         then get 0
  185.       else put 1 into ActiveXcmdBlk@.resultx
  186.     else put 1 into ActiveXcmdBlk@.resultx
  187.   else if it=27 then -- 027,returntopas
  188.     put ActiveXcmdBlk@.inargs.long into aptr
  189.     put ActiveXcmdBlk@.inargs.off4.long into this
  190.     repeat 255
  191.       get chartonum(aptr@.chr)
  192.       if it<32 then if it=13 or it=0 then exit repeat
  193.       add 1 to aptr
  194.       add 1 to this
  195.       put numtochar(it) into this@.chr
  196.       end repeat
  197.     put ActiveXcmdBlk@.inargs.off4.long into aptr
  198.     put numtochar(this-aptr) into aptr@.chr
  199.     end if
  200.   --- DebugStr ";g"
  201. end SimpleCallback
  202.  
  203. on WindowStuff
  204.   DebugStr "oops"
  205. end WindowStuff
  206.  
  207. on CallBackVector 
  208.   ShellHook -- 000,ShellHook
  209.   TextCommand -- 001,sendcardmessage
  210.   EvalExpn -- 002,evalexpr
  211.   SimpleCallback -- 003,stringlength
  212.   SimpleCallback -- 004,stringmatch
  213.   TextCommand -- 005,sendhcmessage
  214.   SimpleCallback -- 006,zerobytes
  215.   SimpleCallback -- 007,pastozero
  216.   SimpleCallback -- 008,zerotopas
  217.   SimpleCallback -- 009,strtolong
  218.   SimpleCallback -- 010,strtonum
  219.   SimpleCallback -- 011,strtobool
  220.   SimpleCallback -- 012,strtoext
  221.   SimpleCallback -- 013,longtostr
  222.   SimpleCallback -- 014,numtostr
  223.   SimpleCallback -- 015,numtohex
  224.   SimpleCallback -- 016,booltostr
  225.   SimpleCallback -- 017,exttostr
  226.   SimpleCallback -- 018,getglobal
  227.   SimpleCallback -- 019,setglobal
  228.   fieldAccess -- 020,getfieldbyname
  229.   fieldAccess -- 021,getfieldbynum
  230.   fieldAccess -- 022,getfieldbyid
  231.   fieldAccess -- 023,setfieldbyname
  232.   fieldAccess -- 024,setfieldbynum
  233.   fieldAccess -- 025,setfieldbyid
  234.   SimpleCallback -- 026,stringequal
  235.   SimpleCallback -- 027,returntopas
  236.   SimpleCallback -- 028,scantoreturn
  237.   notImplemented -- 029,getmaskanddata
  238.   notImplemented -- 030,changedmaskanddata
  239.   notImplemented -- 031,formatscript
  240.   SimpleCallback -- 032,zerotermhandle
  241.   notImplemented -- 033,printtehandle
  242.   SimpleCallback -- 034,sendhcevent
  243.   notImplemented -- 035,hcwordbreakproc
  244.   WindowStuff -- 036,beginxsound
  245.   WindowStuff -- 037,endxsound
  246.   notImplemented -- 038,runhandler
  247.   SimpleCallback -- 039,scantozero
  248.   SimpleCallback -- 040,getxresinfo
  249.   SimpleCallback -- 041,getfilepath
  250.   SimpleCallback -- 042,frontdocwindow
  251.   SimpleCallback -- 043,pointtostr
  252.   SimpleCallback -- 044,recttostr
  253.   SimpleCallback -- 045,strtopoint
  254.   SimpleCallback -- 046,strtorect
  255.   notImplemented -- 047,getfieldte
  256.   notImplemented -- 048,setfieldte
  257.   notImplemented -- 049,getobjectname
  258.   notImplemented -- 050,getobjectscript
  259.   notImplemented -- 051,setobjectscript
  260.   notImplemented -- 052,stacknametonum
  261.   notImplemented -- 053,notify
  262.   notImplemented -- 054,showhcalert
  263.   notImplemented -- 055
  264.   WindowStuff -- 100,getnewxwindow,newxwindow
  265.   WindowStuff -- 101,closexwindow
  266.   WindowStuff -- 102,setxwidletime
  267.   WindowStuff -- 103,xwhasinterruptcode
  268.   WindowStuff -- 104,registerxwmenu
  269.   WindowStuff -- 105,beginxwedit,endxwedit
  270.   notImplemented -- 106,savexwscript
  271.   notImplemented -- 107,getcheckpoints
  272.   notImplemented -- 108,setcheckpoints
  273.   WindowStuff -- 109,xwallowreentrancy
  274.   WindowStuff -- 110,sendwindowmessage
  275.   notImplemented -- 111,hidehcpalettes
  276.   notImplemented -- 112,showhcpalettes
  277.   WindowStuff -- 113,xwalwaysmovehigh
  278. end CallBackVector
  279.  
  280. on myGlobals -- to save A6 in
  281.   DebugStr "oops"
  282. end myGlobals
  283.  
  284. on CallBackDispatcher 
  285.   inline $48E7,$FFFE,+60,$7E00,*myGlobals,$2C50 -- save regs, reload
  286.   put ActiveXcmdBlk into oldXcmdBlock
  287.   put newXcmdBlock into ActiveXcmdBlk
  288.   inline *myHandles,$2C10,*myXcmdBlock,$2848,*newXcmdBlock,$208C
  289.   put 0 into ActiveXcmdBlk@.resultx
  290.   put nil into ActiveXcmdBlk@.outargs1.long
  291.   put nil into ActiveXcmdBlk@.outargs1.off4.long
  292.   put nil into ActiveXcmdBlk@.outargs1.off8.long
  293.   put nil into ActiveXcmdBlk@.outargs1.off8.off4.long
  294.   inline *ActiveXcmdBlk
  295.   --- DebugStr ";dm a7 80;dm @a0 70;g"
  296.   get ActiveXcmdBlk@.request
  297.   if it<114 and it>0 or it=16384 then 
  298.     if it=16384 then get 0
  299.     else if it>55 then get it-44    -- 100 -> 56
  300.     inline *it,$2010,$E580,*CallBackVector,$4EB0,$000C
  301.   else notImplemented
  302.   if ActiveXcmdBlk@.resultx=1 then 
  303.     put "failedcallback" into Nextoken
  304.     tryForXcmd
  305.     if ActiveXcmdBlk@.resultx=2 then put 1 into ActiveXcmdBlk@.resultx
  306.     end if
  307.   inline *ActiveXcmdBlk
  308.   --- DebugStr ";dm @a0 80;g"
  309.   put ActiveXcmdBlk into newXcmdBlock
  310.   put oldXcmdBlock into ActiveXcmdBlk
  311.   inline $4CDF,$7FFF,-60 -- then exit normally
  312. end CallBackDispatcher
  313.  
  314. on myGrowZone gotit,needBytes
  315.   DebugStr "oops"
  316.   get needBytes+gotit
  317. end myGrowZone
  318.  
  319. on InitializeAll initstoo
  320.   --- DebugStr ";g"
  321.   if initstoo then inline $2C4D -- copy A5 to A6
  322.   inline *myHandles,$2086,*myGlobals,$208E -- save D6,A6
  323.   put 0 into this
  324.   inline *CallBackDispatcher,$2008,*this,$2080
  325.   put this into myXcmdBlock.off64.off8.long
  326.   inline *myXcmdBlock,$2848,*newXcmdBlock,$208C
  327.   inline *CallBackVector,$2008,*this,$2080
  328.   add 12 to this
  329.   repeat 70
  330.     put $6000 into this@.int
  331.     add 4 to this
  332.     end repeat
  333.   inline *expnValu,$2008,*exValPtr,$2080
  334.   inline *QuickDraw,$2008,*this,$2080
  335.   InitGraf this+240
  336.   if GetTrapAddressNewOS($A055)=GetTrapAddressNewTool($A89F) 
  337.     then put Lo3Bytes into Stripper
  338.     else put StripAddress(-1) into Stripper
  339.   put WorkingStringAdr()-512 into tokad
  340.   put GetResource("DATA",129) into NameList
  341.   if NameList is nil then ErrorOffQuick
  342.   get HandlePeekLong(NameList,4)
  343.   SetHandleSize NameList,it
  344.   if GetHandleSize(NameList) is not it then ErrorOffQuick
  345.   put GetResource("DATA",128) into OffList
  346.   if OffList is nil then ErrorOffQuick
  347.   get HandlePeekLong(OffList,4)
  348.   SetHandleSize OffList,it
  349.   if GetHandleSize(OffList) is not it then ErrorOffQuick
  350.   put CurResFile() into this
  351.   put "XCMD" into theType
  352.   put 0 into FuncNames
  353.   put 0 into HCardX
  354.   repeat 2
  355.     put FuncNames into CommNames
  356.     if FuncNames is not 0 then
  357.       put "XFCN" into theType
  358.       put HandlePeekLong(OffList,12) into FuncNames
  359.     else put HandlePeekLong(OffList,8) into FuncNames
  360.     get 0
  361.     repeat with index=1 to Count1Resources(theType)
  362.       get 0
  363.       put Get1IndResource(theType,index) into hand
  364.       if GetHandleSize(hand)>33000 then put true into initstoo
  365.       GetResInfo hand,theID,theType,Nextoken
  366.       put tokad+StrLength(Nextoken) into offs
  367.       if offs@.chr="•" then
  368.         put 32768 into offs
  369.         put tokad@.int-256 into tokad@.int
  370.       else put 0 into offs
  371.       DeCapToken
  372.       if StrLength(Nextoken)+NameList@@.long+2>HandlePeekLong(NameList,4) then
  373.         get HandlePeekLong(NameList,4)+256
  374.         SetHandleSize NameList,it
  375.         if GetHandleSize(NameList) is not it then ErrorOffQuick
  376.         HandlePokeLong it,NameList,4
  377.         end if
  378.       if OffList@@.long+16>HandlePeekLong(OffList,4) then
  379.         get HandlePeekLong(OffList,4)+256
  380.         SetHandleSize OffList,it
  381.         if GetHandleSize(OffList) is not it then ErrorOffQuick
  382.         HandlePokeLong it,OffList,4
  383.         end if
  384.       get OffList@@.long
  385.       put it+16 into OffList@@.long
  386.       HandlePokeLong HandlePeekLong(NameList,0),OffList,it
  387.       HandlePokeLong FuncNames,OffList,it+4
  388.       HandlePokeLong theID*65536+offs,OffList,it+8
  389.       HandlePokeLong 0,OffList,it+12
  390.       put it into FuncNames
  391.       put NameList@@.long+NameList@.long into aptr
  392.       put Nextoken into aptr@.str
  393.       put NameList@@.long+StrLength(Nextoken)+2-StrLength(Nextoken) mod 2 into NameList@@.long
  394.       if offs>0 then if theType="XCMD" then if Nextoken="hypercard" 
  395.         then put FuncNames into HCardX
  396.       get 0
  397.       end repeat
  398.     get 0
  399.     end repeat
  400.   put HandlePeekLong(OffList,16) into GlobNames
  401.   put GlobNames into ResWords
  402.   put GetResource("INTL",0) into Intl0
  403.   if Intl0=nil then ErrorOffQuick
  404.   HNoPurge Intl0
  405.   if initstoo then
  406.     InitFonts
  407.     InitWindows
  408.     TEInit
  409.     InitDialogs nil
  410.     end if
  411.   InitCursor
  412.  
  413.   get DoMyCommand(0) 
  414.   repeat with index=1 to 255
  415.     put numtochar(index) into UpperStr.chr[index]
  416.     end repeat
  417.   put numtochar(255) into UpperStr.chr
  418.   UprString UpperStr.str,true
  419.   --SetGrowZone this
  420.   put 0 into currentX
  421.   put 0 into WinSeqNum
  422.   put 0 into hasEdit
  423.   put 0 into hasSound
  424.   put WMgrPort into XgrafPort
  425.   --- DebugStr ";g"
  426. end InitializeAll
  427.  
  428. function DoMyCommand theCode
  429.   --- DebugStr ";g"
  430.   if theCode=0 then 
  431.     inline *DoMyCommand,$2008,*theCode,$2080
  432.     put theCode+12 into doMyCommAd
  433.     return true
  434.   else if theCode<0 then 
  435.     put -theCode into theCode
  436.     put theCode mod 2 ≠0 into tf
  437.     get theCode div 2
  438.     if it=1 then return false
  439.     return LeftEx(tf,it)
  440.   else if theCode<32 then return CommandParse(theCode)
  441.     else return FunctionParse(theCode)
  442.   --- DebugStr ";g"
  443. end DoMyCommand
  444.  
  445. function CommandParse theCode
  446.   --- DebugStr ";g"
  447.   INLINE $9EFC,$0220,+544
  448.   put CPUstackPtr() into sptr
  449.   if theCode=31 then return true -- any system msg 
  450.   else if theCode=30 then -- quit
  451.     ExitToShell 
  452.   else if theCode+0=1 then -- get
  453.     if not ParseExpn(chartonum("H"),true) then return false
  454.     PutIntoIt
  455.   else if theCode=2 then -- put 
  456.     if not ParseExpn(0,true) then return false
  457.     put "into,before,after" into WorkingString
  458.     put TokIsItemOfWS() into offs
  459.     return PutItThere(offs)
  460.   else if theCode=5 then -- beep
  461.     if not ParseExpn(chartonum("I"),true) then put 1 into expnValu.long
  462.     repeat expnValu.long mod 8
  463.       SysBeep 20
  464.       end repeat
  465.   else return false
  466.   --- DebugStr ";g"
  467.   return true
  468. end CommandParse
  469.  
  470. function FunctionParse theCode
  471.   --- DebugStr ";g"
  472.   INLINE $9EFC,$0208,+520
  473.   put CPUstackPtr() into sptr
  474.   put (FirstCharOf(Nextoken)="(") into parens
  475.   if theCode+0=33 then -- ticks
  476.     put ticks into expnValu.long
  477.     put "I" into expnType
  478.   else if theCode=34 then -- seconds
  479.     put Time into expnValu.long
  480.     put "U" into expnType
  481.   else if theCode=39 then -- result 
  482.     put resValue into expnValu.long
  483.     if resType="H" then get HandToHand(expnValu.ptrtype)
  484.     put resType into expnType
  485.   else if theCode=66 then -- screenrect
  486.     put ScreenBits.bounds.topLeft into expnValu.topLeft
  487.     put ScreenBits.bounds.botRight into expnValu.botRight
  488.     put "Y" into expnType
  489.   else return false
  490.   if parens then Getokenn
  491.   --- DebugStr ";g"
  492.   return true
  493. end FunctionParse
  494.  
  495. function PutItThere kin -- kin selects from: into,before,after
  496.   --- DebugStr ";g"
  497.   INLINE $9EFC,$0208,+520
  498.   put CPUstackPtr() into sptr
  499.   put expnPtr into xptr
  500.   Getokenn
  501.   put xptr into expnPtr
  502.   SaveExpn exValPtr-4,sptr
  503.   Getokenn
  504.   if not LeftEx(false,0) 
  505.     then return DisposeIfHandle(chartonum(sptr@.chr),sptr@.off4.long)
  506.   put expnValu.off4.long into offs
  507.   if expnType="K" then
  508.     put sptr+260 into xptr
  509.     BlockMove exValPtr,xptr,12
  510.     SaveExpn sptr,exValPtr-4
  511.     if not InBitSet(chartonum(expnType)-64,$80100) -- HS
  512.       then ConvertType chartonum("S")
  513.     if expnType="H" then
  514.       put StringLength(expnValu@.long) into len
  515.       put expnValu@.long into aptr
  516.     else
  517.       put StrLength(expnValu.str) into len -- "S"    
  518.       put exValPtr+1 into aptr
  519.       end if
  520.     if xptr@.long=nil then 
  521.       if xptr@.off8.long=len then BlockMove aptr,xptr@.off4.long,len
  522.         else return DisposeIfHandle(chartonum(expnType),expnValu.long)
  523.     else
  524.       if expnType="H" then if expnValu.long is not nil
  525.         then HLock expnValu.long
  526.       get Munger(xptr@.long,xptr@.off4.long,nil,xptr@.off8.long,aptr,len)
  527.       get DisposeIfHandle(chartonum(expnType),expnValu.long)
  528.       end if
  529.   else if expnType="Q" then return false
  530.   else 
  531.     get chartonum(sptr@.chr)
  532.     if InBitSet(it mod 32,$84002) then -- .,A,N,S
  533.       get chartonum("S")
  534.       put sptr+4 into aptr
  535.     else put sptr@.off4.long into aptr
  536.     return PutGlobal(offs,it,aptr)
  537.     end if
  538.   --- DebugStr ";g"
  539.   return true
  540.   get kin+0
  541. end PutItThere
  542.  
  543. function CallCode offoff,fraim,pramex,flags
  544.   --- DebugStr ";g"
  545.   ZeroBytes fraim,128
  546.   if pramex>0 then Getokenn
  547.   put 0 into offs
  548.   put fraim+2 into aptr
  549.   repeat
  550.     if pramex=0 or StrLength(Nextoken)=0 or FirstCharOf(Nextoken)=")"
  551.       then exit repeat
  552.     if ParseExpn(chartonum("H"),false) is false then return false
  553.     add 1 to offs
  554.     put offs into fraim@.int
  555.     put expnValu.long into aptr@.long
  556.     add 4 to aptr
  557.     if offs=pramex then exit repeat
  558.     if FirstCharOf(Nextoken)="," then Getokenn
  559.     end repeat
  560.   return CallXCode(offoff+0,fraim,flags+0)
  561. end CallCode
  562.  
  563. function ParseExpn typeWanted,readtoken
  564.   --- DebugStr ";g"
  565.   if readtoken then Getokenn
  566.   if BoolTermEx(0) is false then return false
  567.   repeat while Nextoken="or" 
  568.     Getokenn
  569.     ConvertType chartonum("B")
  570.     put expnValu.long into savedExpn
  571.     if BoolTermEx(chartonum("B")) is false then return false
  572.     if savedExpn is not zero then put 1 into expnValu.long
  573.     end repeat
  574.   ConvertType typeWanted+0
  575.   --- DebugStr ";g"
  576.   return true
  577. end ParseExpn
  578.  
  579. function BoolTermEx typeWanted
  580.   --- DebugStr ";g"
  581.   if BoolFactEx(0) is false then return false
  582.   repeat while Nextoken="and" 
  583.     Getokenn
  584.     ConvertType chartonum("B")
  585.     put expnValu.long into savedExpn
  586.     if BoolFactEx(chartonum("B")) is false then return false
  587.     if savedExpn is zero then put 0 into expnValu.long
  588.     end repeat
  589.   ConvertType typeWanted+0
  590.   --- DebugStr ";g"
  591.   return true
  592. end BoolTermEx
  593.  
  594. function BoolFactEx typeWanted
  595.   --- DebugStr ";g"
  596.   INLINE $9EFC,$0110,+272
  597.   put CPUstackPtr() into sptr
  598.   if BoolPrimEx(0) is false then return false
  599.   put "<,≤,>,≥,=,≠,,,contains,is" into WorkingString
  600.   get TokIsItemOfWS()
  601.   if it>0 then
  602.     Getokenn
  603.     if it=3 then
  604.       if FirstCharOf(Nextoken)="=" then 
  605.         Getokenn
  606.         get 4
  607.         end if
  608.     else if it=10 then get 5
  609.     else if it=1 then
  610.       if FirstCharOf(Nextoken)="=" then get 2
  611.       else if FirstCharOf(Nextoken)=">" then get 6
  612.       if it>1 then Getokenn
  613.       end if
  614.     put it into opr
  615.     if opr<7 then
  616.       SaveExpn exValPtr-4,sptr+12
  617.       put chartonum(expnType) into saveType
  618.       BlockMove exValPtr,sptr+12,256
  619.       if expnType="F" then get saveType else get 0
  620.       if BoolPrimEx(it) is false then
  621.         return DisposeIfHandle(saveType,sptr@.off16.long)
  622.       else 
  623.         if expnType="H" then 
  624.           put expnValu.long@.long into p2
  625.           put StringLength(p2) into n2
  626.         else if expnType="K" then 
  627.           put expnValu.long into p2
  628.           if p2≠0 then put p2@.long into p2
  629.           put p2+expnValu.off4.long into p2
  630.           put expnValu.off8.long into n2
  631.         else 
  632.           put StrLength(expnValu.str) into n2
  633.           put exValPtr+1 into p2
  634.           end if
  635.         if numtochar(saveType)="H" then 
  636.           put sptr@.off16.long@.long into p1
  637.           put StringLength(p1) into n1
  638.         else if numtochar(saveType)="K" then 
  639.           put sptr@.off16.long into p2
  640.           if p2≠0 then put p2@.long into p2
  641.           put p2+sptr@.off16.off4.long into p2
  642.           put sptr@.off16.off8.long into n2
  643.         else 
  644.           put StrLength(sptr@.off16.str) into n1
  645.           put sptr+17 into p1
  646.           end if
  647.         if opr<5 then put IUMagString(p1,p2,n1,n2) into cmpr
  648.           else put IUMagIDString(p1,p2,n1,n2) into cmpr
  649.         end if
  650.       get DisposeIfHandle(chartonum(expnType),expnValu.long)
  651.       get DisposeIfHandle(saveType,sptr@.off16.long)
  652.       if opr<5 then 
  653.         if opr mod 2 =0 then put opr-cmpr≠3 into expnValu.bool
  654.           else put opr-cmpr-2=0 into expnValu.bool
  655.       else put opr-abs(cmpr)-5=0 into expnValu.bool
  656.     else  return false
  657.     put "B" into expnType
  658.     end if
  659.   ConvertType typeWanted+0
  660.   --- DebugStr ";g"
  661.   return true
  662. end BoolFactEx
  663.  
  664. function BoolPrimEx typeWanted
  665.   --- DebugStr ";g"
  666.   if STermEx(0) is false then return false
  667.   ConvertType typeWanted+0
  668.   --- DebugStr ";g"
  669.   return true
  670. end BoolPrimEx
  671.  
  672. function SExpnEx typeWanted 
  673.   --- DebugStr ";g"
  674.   INLINE $9EFC,$0010,+16
  675.   put CPUstackPtr() into sptr
  676.   if STermEx(0) is false then return false
  677.   repeat 
  678.     put chartonum(FirstCharOf(Nextoken)) into opr
  679.     if not InBitSet(opr-32,$2800) then exit repeat -- +,-
  680.     Getokenn
  681.     ConvertType chartonum("F")
  682.     MathFunction 0,sptr
  683.     if STermEx(chartonum("F")) is false then return false
  684.     if numtochar(opr)="+" then MathFunction 4,sptr
  685.       else MathFunction 5,sptr
  686.     end repeat
  687.   ConvertType typeWanted+0
  688.   --- DebugStr ";g"
  689.   return true
  690. end SExpnEx
  691.  
  692. function STermEx typeWanted
  693.   --- DebugStr ";g"
  694.   INLINE $9EFC,$0010,+16
  695.   put CPUstackPtr() into sptr
  696.   if SFactEx(0) is false then return false
  697.   repeat 
  698.     if StrLength(Nextoken)=1 then put chartonum(FirstCharOf(Nextoken)) into opr
  699.     else if Nextoken="div" then put chartonum("%") into opr
  700.     else if Nextoken="mod" then put chartonum("#") into opr
  701.       else put 0 into opr
  702.     if not InBitSet(opr-32,$8424) then exit repeat -- #,%,*,/
  703.     Getokenn
  704.     if opr<chartonum("*") then
  705.       ConvertType chartonum("I")
  706.       put expnValu.long into saveLong
  707.     else
  708.       ConvertType chartonum("F")
  709.       MathFunction 0,sptr
  710.       end if
  711.     put chartonum(expnType) into saveType
  712.     if SFactEx(chartonum(expnType)) is false then return false
  713.     if numtochar(opr)="#" then MathFunction 3,saveLong
  714.     else if numtochar(opr)="%" then MathFunction 2,saveLong
  715.     else if numtochar(opr)="*" then MathFunction 6,sptr
  716.       else MathFunction 7,sptr
  717.     end repeat
  718.   ConvertType typeWanted+0
  719.   --- DebugStr ";g"
  720.   return true
  721. end STermEx
  722.  
  723. function SFactEx typeWanted 
  724.   --- DebugStr ";g"
  725.   INLINE $9EFC,$0010,+16
  726.   put CPUstackPtr() into sptr
  727.   if SPrimEx(0) is false then return false
  728.   ConvertType typeWanted+0
  729.   --- DebugStr ";g"
  730.   return true
  731. end SFactEx
  732.  
  733. function SPrimEx typeWanted 
  734.   --- DebugStr ";g"
  735.   put true into gotit
  736.   if FirstCharOf(Nextoken)="-" then
  737.     Getokenn
  738.     if SPrimEx(0) is false then return false
  739.     if InBitSet(chartonum(expnType)-64,$15200) then -- I,L,N,P
  740.       ConvertType chartonum("I")
  741.       put -expnValu.long into expnValu.long
  742.     else
  743.       ConvertType chartonum("F")
  744.       MathFunction 1,0
  745.       end if
  746.   else if Nextoken="not" then
  747.     Getokenn
  748.     if SPrimEx(chartonum("B")) is false then return false
  749.     put not expnValu.bool into expnValu.bool
  750.   else if FirstCharOf(Nextoken)="(" then
  751.     if ParseExpn(0,true) is false then return false
  752.     if FirstCharOf(Nextoken)≠")"  
  753.       then return DisposeIfHandle(chartonum(expnType),expnValu.long)
  754.     Getokenn
  755.   else if toknType=quote then
  756.     put "S" into expnType
  757.     put Nextoken into expnValu.str
  758.     Getokenn
  759.   else if toknType="N" or toknType="." then
  760.     put toknType into expnType
  761.     put Nextoken into expnValu.str
  762.     Getokenn
  763.   else if toknType≠"A" then return false
  764.   else
  765.     if Nextoken="the" then
  766.       Getokenn
  767.       put "short,long,abbr,abbrev,abbreviated," into WorkingString
  768.       put TokIsItemOfWS() into funMod
  769.       if funMod>0 then Getokenn
  770.       put Nextoken into expnValu.str
  771.       put expnPtr into savePtr
  772.       Getokenn
  773.       if Nextoken="of" then put 1 into pramex
  774.         else put 0 into pramex
  775.       put savePtr into expnPtr
  776.       put expnValu.str into Nextoken
  777.       put DoFunction(pramex) into gotit
  778.     else 
  779.       put Nextoken into expnValu.str
  780.       put expnPtr into savePtr
  781.       Getokenn
  782.       put Nextoken into WorkingString
  783.       put expnValu.str into Nextoken
  784.       put savePtr into expnPtr
  785.       if FirstCharOf(WorkingString)="(" then put DoFunction(16) into gotit
  786.       else if WorkingString="of" then put DoFunction(1) into gotit
  787.       else 
  788.         if not LeftEx(true,0) then return false
  789.         if expnType="H" then if expnValu.long≠nil 
  790.           then put HandToHand(expnValu.ptrtype)=0 into gotit
  791.         end if
  792.       end if
  793.     if gotit is false then return false
  794.     end if
  795.   ConvertType typeWanted+0 
  796.   --- DebugStr ";g"
  797.   return true
  798. end SPrimEx 
  799.  
  800. function LeftEx derefit, varoff
  801.     put Nextoken into WorkingString
  802.     AppendString ";dm a7+24;g"
  803.     --- DebugStr WorkingString
  804.   put varoff+0 into offs
  805.   if varoff<2 then put LookupName(GlobNames,OffList,NameList) into offs
  806.   if offs is not 0 then
  807.     put OffList@.long+offs+10 into expnValu.long
  808.     put offs into expnValu.off4.long
  809.     put numtochar(HandlePeekByte(OffList,offs+8)) into expnType
  810.     if expnType="C" then
  811.       if derefit then 
  812.         put "S" into expnType
  813.         put HandlePeekByte(OffList,offs+9)+256 into expnValu.int
  814.       else subtract 1 from expnValu.long
  815.     else if expnType="S" then
  816.       if derefit then 
  817.         BlockMove OffList@.long+offs+9,aptr,HandlePeekByte(OffList,offs+9)+1
  818.       else subtract 1 from expnValu.long
  819.     else if expnType="H" then
  820.       put HandlePeekLong(OffList,offs+10) into expnValu.long
  821.     else if derefit then 
  822.       if expnType="F" then BlockMove OffList@.long+offs+10,aptr,12
  823.         else put HandlePeekLong(OffList,offs+10) into expnValu.long -- I,L,P
  824.       end if
  825.   else -- create new global
  826.     put Nextoken into expnValu.str
  827.     put "S" into expnType
  828.     ConvertType chartonum("H")
  829.     if StrLength(Nextoken)+NameList@@.long+2>HandlePeekLong(NameList,4) then
  830.       get HandlePeekLong(NameList,4)+256
  831.       SetHandleSize NameList,it
  832.       if GetHandleSize(NameList) is not it then return false
  833.       HandlePokeLong it,NameList,4
  834.       end if
  835.     if OffList@@.long+14>HandlePeekLong(OffList,4) then
  836.       get HandlePeekLong(OffList,4)+256
  837.       SetHandleSize OffList,it
  838.       if GetHandleSize(OffList) is not it then return false
  839.       HandlePokeLong it,OffList,4
  840.       end if
  841.     put OffList@@.long into offs
  842.     HandlePokeLong HandlePeekLong(NameList,0),OffList,offs
  843.     HandlePokeLong GlobNames,OffList,offs+4
  844.     HandlePokeLong offs+14,OffList,0
  845.     HandlePokeWord chartonum("H")*256,OffList,offs+8
  846.     HandlePokeLong expnValu.long,OffList,offs+10
  847.     put offs into GlobNames
  848.     put offs into expnValu.off4.long
  849.     DeCapToken
  850.     put NameList@@.long+NameList@.long into aptr
  851.     put Nextoken into aptr@.str
  852.     put NameList@@.long+StrLength(Nextoken)+2-StrLength(Nextoken) mod 2 into NameList@@.long
  853.     end if
  854.   if varoff=0 then Getokenn
  855.   ConvertType 0  ---- debug only ----
  856.   --- DebugStr ";g"
  857.   return true
  858. end LeftEx
  859.  
  860. function DoFunction pramex
  861.   --- DebugStr ";g"
  862.   INLINE $9EFC,$0190,+400
  863.   put CPUstackPtr() into fraim
  864.   if pramex<0 then
  865.     put LookupName(HandlePeekLong(OffList,12),OffList,NameList) into offs
  866.     put -1-pramex into pramex
  867.   else put LookupName(FuncNames,OffList,NameList) into offs
  868.   if offs is not 0 then
  869.     get HandlePeekWord(OffList,offs+8)
  870.     if it>0 then 
  871.       put fraim+128 into savePtr
  872.       put Nextoken into savePtr@.str
  873.       put expnPtr into savePtr
  874.       if pramex>0 then Getokenn
  875.       if CallCode(offs,fraim,pramex,32768) is false then return false
  876.       if fraim@.passflag then 
  877.         get DisposeIfHandle(chartonum(expnType),expnValu.long)
  878.         put savePtr into expnPtr
  879.         put fraim+128 into savePtr
  880.         put savePtr@.str into Nextoken
  881.         return DoFunction(-1-pramex)
  882.       else return true
  883.     else return DoMyCommand(-it)
  884.   else return false
  885.   --- DebugStr ";g"
  886. end DoFunction
  887.  
  888. function PutGlobal offs, itsType, theVal 
  889.   --- DebugStr ";dm a7+1C;g"
  890.   put numtochar(HandlePeekByte(OffList,offs+8)) into tempChar
  891.   if itsType≠0 then
  892.     put numtochar(itsType) into expnType
  893.     if expnType="S" then 
  894.       put theVal@.str into expnValu.str
  895.     else if InBitSet(chartonum(expnType)-64,$6000040) then -- F,Y,Z
  896.       BlockMove theVal,exValPtr,14
  897.     else put theVal into expnValu.long
  898.     end if
  899.   ConvertType chartonum(tempChar)
  900.   put OffList@.long+offs+10 into aptr
  901.   if expnType="H" then
  902.     get aptr@.long
  903.     put expnValu.long into aptr@.long
  904.     get DisposeIfHandle(chartonum("H"),it)
  905.   else if InBitSet(chartonum(expnType)-64,$1311200) then -- I,L,P,T,U,X
  906.     put expnValu.long into aptr@.long
  907.   else if expnType="F" then MathFunction 0,aptr
  908.   else if InBitSet(chartonum(expnType)-64,$6) then -- B,C
  909.     subtract 1 from aptr
  910.     put expnValu.chr into aptr@.chr
  911.   else if expnType="S" then
  912.     subtract 1 from aptr
  913.     if aptr@.chr=expnValu.chr then put expnValu.str into aptr@.str
  914.       else return false
  915.   else if expnType="Y" then
  916.     put expnValu.long into aptr@.long
  917.     put expnValu.off4.long into aptr@.off4.long
  918.   else if expnType="Z" then BlockMove exValPtr,aptr,14
  919.     else return false
  920.   --- DebugStr ";g"
  921.   return true
  922. end PutGlobal
  923.  
  924. on PutIntoIt
  925.   --- DebugStr ";g"
  926.   put "it" into Nextoken
  927.   put LookupName(GlobNames,OffList,NameList) into offs
  928.   if offs>0 then return PutGlobal(offs,0,0)
  929.     else return DisposeIfHandle(chartonum(expnType),expnValu.long)
  930.   --- DebugStr ";g"
  931. end PutIntoIt
  932.  
  933. function CallXCode offoff,fraim,flags
  934.   --- DebugStr ";dm a7+30 30;g"
  935.   -- load XCMD or XFCN, parse its params into newXcmdBlock, and call it
  936.   put HandlePeekWord(OffList,offoff+10)+1 into recurs
  937.   if recurs=0 then return false
  938.   if recurs > -2 then HandlePokeWord recurs,OffList,offoff+10
  939.   put HandlePeekWord(OffList,offoff+8) into resID
  940.   if BitAnd(flags,32768)=0 then put "XCMD" into expnValu.OStype
  941.     else put "XFCN" into expnValu.OStype
  942.   put GetResource(expnValu.OStype,resID) into hand
  943.   if hand is nil then return false
  944.   if hand ≠ HandlePeekLong(OffList,offoff+12) then
  945.     HandlePokeLong hand,OffList,offoff+12
  946.     if recurs<0 then put -1 into recurs
  947.       else put 1 into recurs
  948.     HandlePokeWord recurs,OffList,offoff+10
  949.     end if
  950.   if recurs<2 then if flags mod 8 > 1 then MoveHHi hand  -- *** not 64K ROMs ***
  951.   HLock hand
  952.   put newXcmdBlock into oldXcmdBlock
  953.   put fraim into newXcmdBlock
  954.   put fraim@.int into offs
  955.   put currentX into oldX
  956.   put offoff into currentX
  957.   if fraim@.int≥0 then SetPort XgrafPort
  958.   put oldXcmdBlock@.off64.off8.long into newXcmdBlock@.off64.off8.long
  959.   inline *newXcmdBlock,$2F10,+4,*hand,$2050,$2050,$4E90,-4
  960.   put newXcmdBlock@.passFlag into passed
  961.   put newXcmdBlock@.returnvalue into expnValu.long
  962.   put "H" into expnType
  963.   put newXcmdBlock+2 into fraim
  964.   repeat offs
  965.     get fraim@.long
  966.     if it is not nil then if it≠expnValu.long then DisposHandle it
  967.     add 4 to fraim
  968.     end repeat
  969.   put oldX into currentX
  970.   put oldXcmdBlock into newXcmdBlock
  971.   get HandlePeekWord(OffList,offoff+10)
  972.   if it> -2 then HandlePokeWord it-1,OffList,offoff+10
  973.   if it<2 then if flags mod 4 < 2 then HUnlock hand
  974.   --- DebugStr ";g"
  975.   return not passed
  976. end CallXCode
  977.  
  978. on ConvertType typeWanted 
  979.   inline *exValPtr
  980.   --- DebugStr ";dm a7+20;dm a0;g"
  981.   INLINE $9EFC,$0100,+256
  982.   put CPUstackPtr() into sptr
  983.   put numtochar(typeWanted) into tempChar
  984.   if tempChar<"B" then exit ConvertType
  985.   if expnType="." or expnType="N" then put "S" into expnType
  986.   if expnType="S" then if StrLength(expnValu.str)=0 then
  987.     put 0 into expnValu.long
  988.     if tempChar="H" then put tempChar into expnType
  989.     end if
  990.   if tempChar=expnType then exit ConvertType
  991.   if InBitSet(chartonum(expnType)-64,$1311200) and InBitSet(typeWanted-64,$1311200)
  992.     then get 0 -- both I,L,P,T,U,X
  993.   else if expnType="S" and tempChar="H" then 
  994.     put StrLength(expnValu.str) into len
  995.     put NewHandle(len+1) into hand
  996.     if hand is not nil then
  997.       BlockMove exValPtr+1,hand@,len
  998.       HandlePokeByte 0,hand,len
  999.       end if
  1000.     put hand into expnValu.long
  1001.   else if expnType="H" and tempChar="S" then 
  1002.     put expnValu.long into hand
  1003.     if hand is not nil then
  1004.       put StringLength(hand@.long) into len
  1005.       if len>255 then put 255 into len
  1006.       BlockMove hand@,exValPtr+1,len
  1007.       put numtochar(len) into expnValu.chr
  1008.       DisposHandle hand
  1009.       end if
  1010.   else if tempChar="B" then 
  1011.     if not InBitSet(chartonum(expnType)-64,$211200) then -- I,L,P,U
  1012.       ConvertType chartonum("S")
  1013.       put expnValu.str into expnValu.bool
  1014.       put "B" into tempChar
  1015.     else put expnValu.long mod 2 into expnValu.bool
  1016.   else if expnType="B" then 
  1017.     if not InBitSet(typeWanted-64,$211200) then -- I,L,P,U
  1018.       put expnValu.bool into expnValu.str
  1019.       put "S" into expnType
  1020.       ConvertType typeWanted
  1021.     else put expnValu.bool into expnValu.long
  1022.   else if expnType="U" then 
  1023.     if tempChar="F" then
  1024.       MathFunction 13,aptr
  1025.       put "F" into expnType
  1026.     else
  1027.       LongToStr expnValu.long,exValPtr
  1028.       put "S" into expnType
  1029.       ConvertType typeWanted
  1030.       end if
  1031.   else if expnType="F" then
  1032.     if not InBitSet(typeWanted-64,$211200) then -- I,L,P,U
  1033.       MathFunction 15,aptr
  1034.       put "S" into expnType
  1035.       ConvertType typeWanted
  1036.     else MathFunction 11,aptr
  1037.   else if tempChar="F" then
  1038.     if not InBitSet(chartonum(expnType)-64,$11200) then -- I,L,P
  1039.       ConvertType chartonum("S")
  1040.       MathFunction 14,aptr
  1041.       put "F" into tempChar
  1042.     else MathFunction 12,aptr
  1043.   else if InBitSet(chartonum(expnType)-64,$11200) then
  1044.     put expnValu.long into expnValu.str
  1045.     put "S" into expnType
  1046.     ConvertType typeWanted
  1047.   else if InBitSet(typeWanted-64,$11200) then 
  1048.     ConvertType chartonum("S")
  1049.     put expnValu.str into expnValu.long
  1050.     put "L" into tempChar
  1051.   else if expnType="X" then 
  1052.     IntArray sptr,exValPtr,-2
  1053.     put sptr@.str into expnValu.str
  1054.     put "S" into expnType
  1055.     ConvertType typeWanted
  1056.   else if expnType="Y" then 
  1057.     IntArray sptr,exValPtr,-4
  1058.     put sptr@.str into expnValu.str
  1059.     put "S" into expnType
  1060.     ConvertType typeWanted
  1061.   else if tempChar="X" then 
  1062.     ConvertType chartonum("S")
  1063.     put expnValu.str into sptr@.str
  1064.     IntArray sptr,exValPtr,2
  1065.     put "X" into tempChar
  1066.   else if tempChar="Y" then 
  1067.     ConvertType chartonum("S")
  1068.     put expnValu.str into sptr@.str
  1069.     IntArray sptr,exValPtr,4
  1070.     put "Y" into tempChar
  1071.   else if tempChar="C" then
  1072.     put expnValu.long into hand
  1073.     if expnType≠"H" then 
  1074.       ConvertType chartonum("S")
  1075.       put expnValu.str into expnValu.chr
  1076.       put "C" into expnType
  1077.     else if hand is not nil then
  1078.       put hand@@.chr into expnValu.chr
  1079.       DisposHandle hand
  1080.       end if
  1081.   else if expnType="C" then 
  1082.     put expnValu.chr into expnValu.str
  1083.     put "S" into expnType
  1084.     ConvertType typeWanted
  1085.   else if expnType="T" then 
  1086.     put expnValu.long into expnValu.off8.long
  1087.     put expnValu.off8.OStype into expnValu.str
  1088.     put "S" into expnType
  1089.     ConvertType typeWanted
  1090.   else if tempChar="T" then
  1091.     put expnValu.long into hand
  1092.     if expnType≠"H" then 
  1093.       ConvertType chartonum("S")
  1094.       put expnValu.str into expnValu.off8.OStype
  1095.       put expnValu.off8.long into expnValu.long
  1096.       put "T" into expnType
  1097.     else if hand is not nil then
  1098.       put hand@@.long into expnValu.long
  1099.       DisposHandle hand
  1100.       end if
  1101.   else exit ConvertType
  1102.   put tempChar into expnType
  1103.   --- DebugStr ";g"
  1104. end ConvertType
  1105.  
  1106. function TokIsItemOfWS
  1107.   --- DebugStr ";g"
  1108.   INLINE $9EFC,$0110,+272
  1109.   put CPUstackPtr() into sptr
  1110.   put WorkingString into sptr@.str
  1111.   ZapString sptr
  1112.   put WorkingStringAdr()-511 into aptr
  1113.   put OffsetString(aptr,StrLength(Nextoken),sptr+1) into offs
  1114.   put offs+sptr+StrLength(Nextoken) into aptr
  1115.   if aptr@.chr is not "," then return 0
  1116.   if offs<2 then return offs
  1117.   put offs+sptr-1 into aptr
  1118.   if aptr@.chr is not "," then return 0
  1119.   put 1 into offs
  1120.   repeat until aptr=sptr
  1121.     if aptr@.chr="," then add 1 to offs
  1122.     subtract 1 from aptr
  1123.     end repeat
  1124.   --- DebugStr ";g"
  1125.   return offs
  1126. end TokIsItemOfWS
  1127.  
  1128. on Getokenn
  1129.   --- DebugStr ";g"
  1130.   put "" into Nextoken
  1131.   put space into toknType
  1132.   put WorkingStringAdr()-512 into tokad
  1133.   repeat while expnPtr@.chr=space
  1134.     add 1 to expnPtr
  1135.     end repeat
  1136.   if expnPtr@.chr<space then exit Getokenn
  1137.   put expnPtr into tokptr
  1138.   put 0 into quotedtok
  1139.   put GetLetter(expnPtr) into letcode
  1140.   if letcode > 256 then
  1141.     if letcode<512 then put "N" into toknType
  1142.       else put "A" into toknType
  1143.     repeat while letcode > 256 
  1144.       add 1 to expnPtr
  1145.       put GetLetter(expnPtr) into letcode
  1146.       if toknType="N" then if HandlePeekByte(Intl0,0)=letcode then 
  1147.         put 768 into letcode
  1148.         put "." into toknType
  1149.         end if
  1150.       end repeat
  1151.   else if letcode=1 then
  1152.     add 1 to expnPtr
  1153.     put expnPtr into tokptr
  1154.     put quote into toknType
  1155.     put GetLetter(expnPtr) into letcode
  1156.     repeat while letcode>1
  1157.       add 1 to expnPtr
  1158.       put GetLetter(expnPtr) into letcode
  1159.       end repeat
  1160.     if letcode>0 then 
  1161.       put 1 into quotedtok
  1162.       add 1 to expnPtr
  1163.     else exit Getokenn
  1164.   else add 1 to expnPtr
  1165.   get expnPtr-tokptr
  1166.   if it=1 then
  1167.     put chartonum(tokptr@.chr) into letcode
  1168.     if letcode>64 and letcode<91 then add 32 to letcode
  1169.     put letcode+256 into tokad@.int
  1170.   else
  1171.     put numtochar(it) into tokad@.chr
  1172.     BlockMove tokptr,tokad+1,it
  1173.     if quotedtok>0 then put numtochar(it-1) into tokad@.chr
  1174.     --  else DeCapToken
  1175.     end if
  1176.   put Nextoken into WorkingString
  1177.     AppendString ";dm a0;g"
  1178.     inline *doMyCommAd
  1179.     --- DebugStr WorkingString
  1180. end Getokenn
  1181.  
  1182. function GetLetter txtptr
  1183.   --- DebugStr ";g"
  1184.   put chartonum(txtptr@.chr) into Nextok
  1185.   if Nextok<32 then return 0
  1186.   if Nextok=34 then return 1
  1187.   if Nextok>=48 and Nextok<58 then return Nextok+256
  1188.   if Nextok=95 then return 607
  1189.   if Nextok>64 and Nextok<91 or Nextok>96 and Nextok<123 then return Nextok+512
  1190.   --- DebugStr ";g"
  1191.   return Nextok
  1192. end GetLetter
  1193.  
  1194. on DeCapToken
  1195.   put WorkingStringAdr()-512 into tokad
  1196.   put BitOr(tokad@.long,$202020) into tokad@.long
  1197.   if StrLength(Nextoken)<2 then put 0 into tokad@.off2.int
  1198.   else if StrLength(Nextoken)<3 then put BitAnd(tokad@.long,-256) into tokad@.long
  1199. end DeCapToken
  1200.  
  1201. function LookupName theList, OffHand, NameHand
  1202.   -- find Nextoken in OffHand beginning at offset theList, return offset if found
  1203.   put WorkingStringAdr()-512 into tokad
  1204.   put BitOr(tokad@.long,$202020) into first4
  1205.   repeat 
  1206.     if theList is 0 then return 0
  1207.     put NameHand@.long+HandlePeekLong(OffHand,theList) into namePtr
  1208.     if namePtr mod 2 = 0 then if first4≠namePtr@.long then if StrLength(namePtr@.str)>2 then 
  1209.       put HandlePeekLong(OffHand,theList+4) into theList
  1210.       next repeat
  1211.       end if
  1212.     if Nextoken=namePtr@.str then 
  1213.         put Nextoken into WorkingString
  1214.         AppendString ";dm a7+24;g"
  1215.         --- DebugStr WorkingString
  1216.       return theList
  1217.     else put HandlePeekLong(OffHand,theList+4) into theList
  1218.     end repeat
  1219. end LookupName
  1220.  
  1221. function InBitSet theNum,theBits
  1222.   if BitAnd(theNum,-32) is not 0 then return false
  1223.   repeat theNum -- *** this could be faster with inline shift
  1224.     put theBits div 2 into theBits
  1225.     end repeat
  1226.   return theBits mod 2 ≠0
  1227. end InBitSet
  1228.  
  1229. function DisposeIfHandle typeCode,hand
  1230.   if numtochar(typeCode)="H" or numtochar(typeCode)="K" 
  1231.     then if hand is not nil then DisposHandle hand
  1232.   return false
  1233. end DisposeIfHandle 
  1234.  
  1235. function OffsetString substr,lens,bigstr -- case insensitive, global-free
  1236.   -- return offset(substr@,bigstr@) where lens=length(substr)
  1237.   put bigstr into aptr
  1238.   if UpperStr.long=0 then
  1239.     repeat with index=1 to 255
  1240.       put numtochar(index) into UpperStr.chr[index]
  1241.       end repeat
  1242.     put numtochar(255) into UpperStr.chr
  1243.     UprString UpperStr.str,true
  1244.     end if
  1245.   put UpperStr.chr[chartonum(substr@.chr)] into UpperStr.chr
  1246.   repeat 
  1247.     repeat while UpperStr.chr[chartonum(aptr@.chr)]≠UpperStr.chr
  1248.       add 1 to aptr
  1249.       end repeat
  1250.     if chartonum(aptr@.chr)=0 then return 0
  1251.     put substr into sptr
  1252.     repeat lens
  1253.       if UpperStr.chr[chartonum(aptr@.chr)]≠UpperStr.chr[chartonum(sptr@.chr)]
  1254.         then exit repeat
  1255.       add 1 to sptr
  1256.       add 1 to aptr
  1257.       end repeat
  1258.     if sptr-substr=lens then return aptr-bigstr-lens+1
  1259.     put aptr-sptr+substr+1 into aptr
  1260.     end repeat
  1261. end OffsetString
  1262.  
  1263. function StringLength theStr -- =ScanToZero
  1264.   put theStr into aptr
  1265.   repeat until chartonum(aptr@.chr)=0
  1266.     add 1 to aptr
  1267.     end repeat
  1268.   return aptr-theStr-1
  1269. end StringLength
  1270.  
  1271. on ZapString theStr
  1272.   -- put terminal null after P-string pointed by theStr
  1273.   put theStr+StrLength(theStr@.str)+1 into sptr
  1274.   put numtochar(0) into sptr@.chr
  1275. end ZapString
  1276.  
  1277. on IntArray theStr,theInts,nints
  1278.   INLINE $9EFC,$0020,+32
  1279.   put CPUstackPtr() into sptr
  1280.   if nints<0 then -- convert array of nints integers into P-string theStr
  1281.     put empty into theStr@.str
  1282.     repeat -nints
  1283.       put theInts@.int into sptr@.str
  1284.       put theStr@.str into WorkingString
  1285.       if StrLength(WorkingString)>0 then AppendChar ","
  1286.       AppendString sptr@.str
  1287.       put WorkingString into theStr@.str
  1288.       add 2 to theInts
  1289.       end repeat
  1290.   else repeat nints 
  1291.     -- extract array of nints integers from theStr into theInts
  1292.     put 0 into thenum
  1293.     put 1 into sign
  1294.     repeat 
  1295.       put theStr@.chr into ch
  1296.       if chartonum(ch)<space then exit repeat
  1297.       add 1 to theStr
  1298.       if ch="-" then put -sign into sign
  1299.       else if ch=space and thenum=0 then next repeat
  1300.       else if ch<"0" then exit repeat
  1301.       else if ch>"9" then exit repeat
  1302.         else put (thenum*4+thenum)*2+chartonum(ch)-48 into thenum
  1303.       end repeat
  1304.     if sign<0 then put -thenum into theInts@.int
  1305.       else put thenum into theInts@.int
  1306.     add 2 to theInts
  1307.     end repeat
  1308.   if false then aChar ch
  1309. end IntArray
  1310.  
  1311. on SaveExpn valPtr, savPtr
  1312.   put valPtr@.chr into savPtr@.chr
  1313.   get chartonum(valPtr@.chr) mod 32
  1314.   if InBitSet(it,$84000) then -- N,S,.
  1315.     if StrLength(valPtr@.off4.str)<4 then get 0 else get 19
  1316.     end if
  1317.   if InBitSet(it,$60A48C0) then -- F,G,K,N,Q,S,Y,Z
  1318.     if it=19 then get StrLength(valPtr@.off4.str)+1 -- "S"
  1319.     else if it=17 then get StrLength(valPtr@.off8.str)+5 -- "Q"
  1320.     else if it=7 and valPtr@.off4.off2.int=20 -- "G"
  1321.       then get StrLength(valPtr@.off4.off8.str)+13
  1322.     else get 14
  1323.     BlockMove valPtr+4,savPtr+4,it
  1324.   else put valPtr@.off4.long into savPtr@.off4.long -- B,C,H,I,L,P,T,U,X
  1325. end SaveExpn
  1326.  
  1327. on LongToStr theLong, theStr
  1328.   if theLong<3000000000 then -- both negative, first digit =2
  1329.     put theLong-1000000000 into theStr@.str
  1330.     add 1 to theStr@.int
  1331.   else if theLong<4000000000 then -- both negative, first digit =3
  1332.     put theLong-2000000000 into theStr@.str
  1333.     add 2 to theStr@.int
  1334.   else if theLong<0 then -- theLong slightly negative, first digit =4
  1335.     put theLong-3000000000 into theStr@.str
  1336.     add 3 to theStr@.int
  1337.   else put theLong into theStr@.str
  1338. end LongToStr
  1339.